﻿using Microsoft.AspNetCore.Http;
using Polaris.Domain.Model.Entity.Exception;
using Polaris.Domain.Model.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

namespace Polaris.Common.Middleware
{
    /// <summary>
    /// 全局异常处理
    /// </summary>
    public class GlobalExceptionMiddleware
    {
        private readonly RequestDelegate next;

        public GlobalExceptionMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await next(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }
        }

        private async Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            int code = (int)ResultCode.GLOBAL_ERROR;
            string msg;
            string error = string.Empty;
            string method = context.Request.Method.ToUpper();
            //var controller = context.GetRouteData().Values["controller"];
            //var action = context.GetRouteData().Values["action"];

            // 获取查询字符串参数
            //var ParamValue = context.GetRequestValue(method);

            //if (context.Request.HasFormContentType)
            //{
            //    ParamValue = context.Request.Form.ToJsonString();
            //}

            //自定义异常
            if (ex is CustomException customException)
            {
                code = customException.Code;
                msg = customException.Message;
                error = customException.LogMsg;
            }
            else if (ex is ArgumentException)//参数异常
            {
                code = (int)ResultCode.PARAM_ERROR;
                msg = ex.Message;
            }
            else
            {
                msg = "There seems to be a problem with the server. Please contact your system administrator";
                error = $"{ex.Message}";
                context.Response.StatusCode = 500;
            }
            var options = new System.Text.Json.JsonSerializerOptions
            {
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase,
                WriteIndented = true
            };

            BaseApiResult apiResult = new(code, msg);
            string responseResult = System.Text.Json.JsonSerializer.Serialize(apiResult, options);
            //string ip = HttpContextExtension.GetClientUserIp(context);
            //var ip_info = IpTool.Search(ip);

            //SysOperLog sysOperLog = new()
            //{
            //    OperIP = ip,
            //    OperUrl = HttpContextExtension.GetRequestUrl(context),
            //    RequestMethod = context.Request.Method,
            //    JsonResult = responseResult,
            //    ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
            //    OperUserName = HttpContextExtension.GetName(context),
            //    //OperLocation = ip_info.Province + " " + ip_info.City,
            //    Method = controller + "." + action + "()",
            //    OperTime = DateTime.Now,
            //    OperParam = ParamValue
            //};
            //var endpoint = GetEndpoint(context);
            //if (endpoint != null)
            //{
            //    var logAttribute = endpoint.Metadata.GetMetadata<LogAttribute>();
            //    if (logAttribute != null)
            //    {
            //        sysOperLog.BusinessType = (int)logAttribute.BusinessType;
            //        sysOperLog.Title = logAttribute?.Title;
            //        sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : "";
            //        sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : "";
            //    }
            //}


            context.Response.ContentType = "text/json;charset=utf-8";
            await context.Response.WriteAsync(responseResult, System.Text.Encoding.UTF8);

            //string errorMsg = $"> 操作人：{sysOperLog.OperUserName}" +
            //    $"\n> 操作地区：{sysOperLog.OperIP}({sysOperLog.OperLocation})" +
            //    $"\n> 操作模块：{sysOperLog.Title}" +
            //    $"\n> 操作地址：{sysOperLog.OperUrl}" +
            //    $"\n> 错误信息：{msg}\n\n> {error}";

            //Log.Error(ex, $"GlobalExceptionMiddleware:{errorMsg}");
            //SysOperLogService.InsertOperlog(sysOperLog);
        }

        //public static Endpoint GetEndpoint(HttpContext context)
        //{
        //    if (context == null)
        //    {
        //        throw new ArgumentNullException(nameof(context));
        //    }

        //    return context.Features.Get<IEndpointFeature>()?.Endpoint;
        //}
    }
}
